home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / aztecnos.arc / TCPCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-13  |  6.6 KB  |  313 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9.  
  10. extern int Tcp_trace;
  11. extern char Notval[];
  12. char *pinet();
  13. static int domss(),dortt(),dotcpstat(),dowindow(),dotcpkick();
  14. static int dotcptr(),dotcpreset(),doirtt(),tstat();
  15.  
  16. /* TCP connection states */
  17. char *Tcpstates[] = {
  18.     "Closed",
  19.     "Listen",
  20.     "SYN sent",
  21.     "SYN received",
  22.     "Established",
  23.     "FIN wait 1",
  24.     "FIN wait 2",
  25.     "Close wait",
  26.     "Closing",
  27.     "Last ACK",
  28.     "Time wait"
  29. };
  30.  
  31. /* TCP closing reasons */
  32. char *Tcpreasons[] = {
  33.     "Normal",
  34.     "Reset/Refused",
  35.     "Timeout",
  36.     "ICMP"
  37. };
  38. /* TCP subcommand table */
  39. struct cmds Tcpcmds[] = {
  40.     "irtt",        doirtt,        0, 0,    NULLCHAR,
  41.     "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>",
  42.     "mss",        domss,        0, 0,    NULLCHAR,
  43.     "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>",
  44.     "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>",
  45.     "status",    dotcpstat,    0, 0,    NULLCHAR,
  46.     "trace",    dotcptr,    0, 0,    NULLCHAR,
  47.     "window",    dowindow,    0, 0,    NULLCHAR,
  48.     NULLCHAR,    NULLFP,        0, 0,    "tcp subcommands: irtt kick mss reset rtt status trace window",
  49. };
  50. int
  51. dotcp(argc,argv)
  52. int argc;
  53. char *argv[];
  54. {
  55.     return subcmd(Tcpcmds,argc,argv);
  56. }
  57. static int
  58. dotcptr(argc,argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.     if(argc < 2)
  63.         printf("TCP state tracing %s\n",Tcp_trace ? "on":"off");
  64.     else {
  65.         if(strcmp(argv[1],"on") == 0)
  66.             Tcp_trace = 1;
  67.         else
  68.             Tcp_trace = 0;
  69.     }
  70.     return 0;
  71. }
  72.  
  73. /* Eliminate a TCP connection */
  74. static int
  75. dotcpreset(argc,argv)
  76. int argc;
  77. char *argv[];
  78. {
  79.     register struct tcb *tcb;
  80.  
  81.     tcb = (struct tcb *)ltop(htol(argv[1]));
  82.     if(!tcpval(tcb)){
  83.         printf(Notval);
  84.         return 1;
  85.     }
  86.     close_self(tcb,RESET);
  87.     return 0;
  88. }
  89.  
  90. /* Set initial round trip time for new connections */
  91. static int
  92. doirtt(argc,argv)
  93. int argc;
  94. char *argv[];
  95. {
  96.     if(argc < 2)
  97.         printf("%lu\n",Tcp_irtt);
  98.     else
  99.         Tcp_irtt = atol(argv[1]);
  100.     return 0;
  101. }
  102.  
  103. /* Set smoothed round trip time for specified TCB */
  104. static int
  105. dortt(argc,argv)
  106. int argc;
  107. char *argv[];
  108. {
  109.     register struct tcb *tcb;
  110.  
  111.     tcb = (struct tcb *)ltop(htol(argv[1]));
  112.     if(!tcpval(tcb)){
  113.         printf(Notval);
  114.         return 1;
  115.     }
  116.     tcb->srtt = atol(argv[2]);
  117.     return 0;
  118. }
  119.  
  120. /* Force a retransmission */
  121. static int
  122. dotcpkick(argc,argv)
  123. int argc;
  124. char *argv[];
  125. {
  126.     register struct tcb *tcb;
  127.  
  128.     tcb = (struct tcb *)ltop(htol(argv[1]));
  129.     if(kick_tcp(tcb) == -1){
  130.         printf(Notval);
  131.         return 1;
  132.     }
  133.     return 0;
  134. }
  135.  
  136. /* Set default maximum segment size */
  137. static int
  138. domss(argc,argv)
  139. int argc;
  140. char *argv[];
  141. {
  142.     if(argc < 2)
  143.         printf("%u\n",Tcp_mss);
  144.     else
  145.         Tcp_mss = atoi(argv[1]);
  146.     return 0;
  147. }
  148.  
  149. /* Set default window size */
  150. static int
  151. dowindow(argc,argv)
  152. int argc;
  153. char *argv[];
  154. {
  155.     if(argc < 2)
  156.         printf("%u\n",Tcp_window);
  157.     else
  158.         Tcp_window = atoi(argv[1]);
  159.     return 0;
  160. }
  161.  
  162. /* Display status of TCBs */
  163. static int
  164. dotcpstat(argc,argv)
  165. int argc;
  166. char *argv[];
  167. {
  168.     register struct tcb *tcb;
  169.  
  170.     if(argc < 2){
  171.         tstat();
  172.     } else {
  173.         tcb = (struct tcb *)ltop(htol(argv[1]));
  174.         if(tcpval(tcb))
  175.             st_tcp(tcb);
  176.         else
  177.             printf(Notval);
  178.     }
  179.     return 0;
  180. }
  181.  
  182. /* Dump TCP stats and summary of all TCBs
  183. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  184.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  185.  */
  186. static int
  187. tstat()
  188. {
  189.     register int i;
  190.     register struct tcb *tcb;
  191.  
  192.     printf("conout %u conin %u reset out %u runt %u chksum err %u bdcsts %u\n",
  193.         Tcp_stat.conout,Tcp_stat.conin,Tcp_stat.resets,Tcp_stat.runt,
  194.         Tcp_stat.checksum,Tcp_stat.bdcsts);
  195.     printf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  196.     for(i=0;i<NTCB;i++){
  197.         for(tcb=Tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  198.             printf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  199.             printf("%-23s",pinet(&tcb->conn.local));
  200.             printf("%-23s",pinet(&tcb->conn.remote));
  201.             printf("%-s",Tcpstates[tcb->state]);
  202.             if(tcb->state == LISTEN && tcb->flags.clone)
  203.                 printf(" (S)");
  204.             printf("\n");
  205.         }
  206.     }
  207.     return 0;
  208. }
  209. /* Dump a TCP control block in detail */
  210. void
  211. st_tcp(tcb)
  212. struct tcb *tcb;
  213. {
  214.     int32 sent,recvd;
  215.  
  216.     if(tcb == NULLTCB)
  217.         return;
  218.     /* Compute total data sent and received; take out SYN and FIN */
  219.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  220.     recvd = tcb->rcv.nxt - tcb->irs;
  221.     switch(tcb->state){
  222.     case LISTEN:
  223.     case SYN_SENT:        /* Nothing received or acked yet */
  224.         sent = recvd = 0;    
  225.         break;
  226.     case SYN_RECEIVED:
  227.         recvd--;    /* Got SYN, no data acked yet */
  228.         sent = 0;
  229.         break;
  230.     case ESTABLISHED:    /* Got and sent SYN */
  231.     case FINWAIT1:        /* FIN not acked yet */
  232.         sent--;
  233.         recvd--;
  234.         break;
  235.     case FINWAIT2:        /* Our SYN and FIN both acked */
  236.         sent -= 2;
  237.         recvd--;
  238.         break;
  239.     case CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  240.     case CLOSING:
  241.     case LAST_ACK:
  242.         sent--;
  243.         recvd -= 2;
  244.         break;
  245.     case TIME_WAIT:        /* Sent and received SYN/FIN, all acked */
  246.         sent -= 2;
  247.         recvd -= 2;
  248.         break;
  249.     }
  250.     printf("Local: %s",pinet(&tcb->conn.local));
  251.     printf(" Remote: %s",pinet(&tcb->conn.remote));
  252.     printf(" State: %s\n",Tcpstates[tcb->state]);
  253.     printf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  254.     printf("Send:");
  255.     printf("%9lx",tcb->iss);
  256.     printf("%9lx",tcb->snd.una);
  257.     printf("%9lx",tcb->snd.nxt);
  258.     printf("%7lu",tcb->resent);
  259.     printf("%6u",tcb->cwind);
  260.     printf("%6u",tcb->ssthresh);
  261.     printf("%6u",tcb->snd.wnd);
  262.     printf("%5u",tcb->mss);
  263.     printf("%6u",tcb->sndcnt);
  264.     printf("%11lu\n",sent);
  265.  
  266.     printf("Recv:");
  267.     printf("%9lx",tcb->irs);
  268.     printf("         ");
  269.     printf("%9lx",tcb->rcv.nxt);
  270.     printf("%7lu",tcb->rerecv);
  271.     printf("      ");
  272.     printf("      ");
  273.     printf("%6u",tcb->rcv.wnd);
  274.     printf("     ");
  275.     printf("%6u",tcb->rcvcnt);
  276.     printf("%11lu\n",recvd);
  277.  
  278.     if(tcb->reseq != (struct reseq *)NULL){
  279.         register struct reseq *rp;
  280.  
  281.         printf("Reassembly queue:\n");
  282.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  283.             printf("  seq x%lx %u bytes\n",rp->seg.seq,rp->length);
  284.         }
  285.     }
  286.     if(tcb->backoff > 0)
  287.         printf("Backoff %u ",tcb->backoff);
  288.     if(tcb->flags.retran)
  289.         printf("Retrying ");
  290.     switch(tcb->timer.state){
  291.     case TIMER_STOP:
  292.         printf("Timer stopped ");
  293.         break;
  294.     case TIMER_RUN:
  295.         printf("Timer running (%ld/%ld ms) ",
  296.          (long)MSPTICK * read_timer(&tcb->timer),
  297.          (long)MSPTICK * dur_timer(&tcb->timer));
  298.         break;
  299.     case TIMER_EXPIRE:
  300.         printf("Timer expired ");
  301.     }
  302.     printf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  303. }
  304. char *
  305. pinet(s)
  306. struct socket *s;
  307. {
  308.     static char buf[30];
  309.  
  310.     sprintf(buf,"%s:%u",inet_ntoa(s->address),s->port);
  311.     return buf;
  312. }
  313.